1. Field of the Invention
The present invention relates to computational systems and, more specifically, to a system that runs modules written in an interpreted bytecode language.
2. Background of the Invention
Bytecode is computer object code that is processed by a program, referred to as a virtual machine, rather than directly by the actual processor on which the processed code runs. A virtual machine converts each bytecode instruction into specific machine-dependant instructions that are executable on the processor. Most high level computer languages employ a different compiler for each different type of operating system. Compiling a bytecode program into a virtual machine language allows a developer to compile the bytecode program only once, even though it may be executed on many different types of processors employing different operating systems.
Programming instructions written in a bytecode are designed to be executed by a virtual machine rather than directly by dedicated hardware. The virtual machine acts as an interface layer between the bytecode and the actual processor on which the bytecode is executed. Interpreted bytecode computer languages provide program developers with a platform-independent language. It is the virtual machine that is adapted for execution of specific computer platforms, rather than the bytecode compiler.
Bytecode languages are used by programming language implementations to reduce dependence on specific hardware since the same binary code can be executed across several different platforms. Compared to machine-specific source code, bytecodes tend to be less abstract and more compact. Since a bytecode program is normally executed by parsing the instructions one at a time using an interpreter, bytecode programs tend to be highly portable. While the underlying virtual machine may not be portable between platforms, the bytecode itself remains highly portable.
Frequently, different parts of an interpreted bytecode program are stored in separate files, similar to object modules. Many language implementations execute a program in two phases, first compiling the source code into bytecode, and then passing the bytecode to the virtual machine. Thus, may object modules are often written in a source code that is compiled into a bytecode, which is then interpreted by a virtual machine.
One commonly used bytecode language is Java™, which uses a bytecode interpreter to translate the bytecode to machine code before execution. Java is an object-oriented programming language with a built-in application programming interface (API) that can handle graphics and user interfaces and that can be used to create applications. Since there is an extensive set of available Java™ API's, Java™ is used extensively by developers, especially those creating Internet applications.
However, because they are interpreted run time, rather than compiled before run time, bytecode implementations often do not execute the functions of a program in the most efficient manner. Sometimes it is desirable to substitute certain modules in a bytecode program with code written in the native language of a machine. This is especially true for modules that are computationally intensive. Modules written in a native language, on the other hand, can be written in the most efficient manner without having to incur the penalties associated with interpreting the bytecode.
The ability to supplement bytecode applications with native code is desirable for a number of reasons. First, computationally-complex operations can usually be performed faster when implemented in native code instead of bytecode. Second, support for native code permits the reuse of algorithms and applications that have been written in existing compiled language for other platforms.
The Java™ language specification does include the ability to declare a method as being implemented in a native language. Native method support as defined in the Java™ language does not provide a way in which a default Java™ implementation can be provided for a native method. If for some reason the native code cannot be used (e.g. due to incompatible hardware, security permissions, etc.), then the method is entirely unusable and the application will not function. Other bytecode based systems may provide a mechanism for packaging both a bytecode and native version of a given method in a single load and the operating system will use the native version if possible, but can default to the bytecode version if needed. However, such a ‘fat binary’ approach packages both implementations as part of a single module. In these systems, native implementations cannot be developed, tested and deployed separately.
In the Java™ language specification, a native method modifier is used to indicate that a particular method is implemented natively. The presence of this modifier indicates to the virtual machine (VM) that the method will be linked to appropriate native code instead of a block of bytecode. Until the library is loaded and linking occurs, the method has no code associated with it and cannot be invoked without an error occurring. When the corresponding library is loaded, the VM updates the method table so that the native methods point to their corresponding functions in the native library.
Typical existing systems, as shown in FIG. 1, will load a bytecode library 10 from which it generates a method table 20. The method table includes a plurality of method entries, each of which points to either a bytecode module or to a native method module. At execution, the virtual machine will execute the modules pointed by the method table as requested by the application. If a native method is pointed to by the method table 20 (as is the case with native methods 4 and 7, in the case shown), the method entries will point to code modules that have been previously loaded on the system. If one of the native method modules is unavailable or is not functioning properly, then the system will enter an error condition, as there is not a bytecode module to replace it.
Therefore, there is a need for a system that allows an interpreted bytecode module to be replaced with a native method module, while preserving the interpreted bytecode module.